#include "SDLPopupMenu.h"

SDLPopupMenu::SDLPopupMenu()
: 
m_Surface(0),
m_Parent(0),
m_isVisible(false),
m_Event(0),
m_mustRender(true)
{
	cNormal.r = 0xff;
	cNormal.g = 0xff;
	cNormal.b = 0x00; //= {0xFF, 0xFF, 0x00 };
	cGray.r = 0x00;
	cGray.g = 0x00;
	cGray.b = 0xff; //= {0x00, 0x00, 0xFF };
	m_dst.x = 0;
	m_dst.y = 0;
	m_dst.w = 0;
	m_dst.h = 0;
	m_Font = TTF_OpenFont("arial.ttf", 10);
	m_pParent = 0;
	m_curr = 0;
}

SDLPopupMenu::SDLPopupMenu(std::vector < pair < std::string, bool > > itemList, 
						   SDL_Color normal, SDL_Color grayed, SDL_Surface *pParent, SDL_Event *event, TTF_Font *font,
						   SDLTextBox *caller)
:
m_Surface(0),
m_Parent(pParent),
m_isVisible(false),
m_Event(event),
m_Font(font),
m_pParent(caller),
m_mustRender(true)
{
	cNormal.r = normal.r;
	cNormal.g = normal.g;
	cNormal.b = normal.b;
	cGray.r = grayed.r;
	cGray.g = grayed.g;
	cGray.b = grayed.b;
	for(int i = 0; i < itemList.size(); i++) m_List.push_back(itemList[i]);
	m_curr = 0;
}

SDLPopupMenu::~SDLPopupMenu() {
	if(m_Font) TTF_CloseFont(m_Font);
	if(m_Surface) SDL_FreeSurface(m_Surface);
}

void SDLPopupMenu::render() {
	int i = 0;
	SDL_Surface *temp;
	std::vector <SDL_Surface *> buffer;
	m_dst.x = 0;
	m_dst.y = 0;
	int w = 0, h = 0;
	for(i = 0; i < m_List.size(); i++) {
		if(m_List[i].second) temp = TTF_RenderText_Solid(m_Font, m_List[i].first.c_str(), cNormal);
		else temp = TTF_RenderText_Solid(m_Font, m_List[i].first.c_str(), cGray);
		h += temp->h;
		if(temp->w > w) w = temp->w;
		buffer.push_back(temp);
		buffer[i]->refcount++;
		SDL_FreeSurface(temp);
	}
	m_dst.w = w;
	m_dst.h = h;
	m_Surface = SDL_CreateRGBSurface(SDL_SWSURFACE | SDL_SRCALPHA, m_dst.w, m_dst.h, 32, 0, 0, 0, 0);
	SDL_SetAlpha(m_Surface, SDL_SRCALPHA, 128);
	for(i = 0; i < buffer.size(); i++) {
		apply_surface(m_dst.x, m_dst.y + (buffer[i]->h * i), buffer[i], m_Surface);
		SDL_FreeSurface(buffer[i]);
	}
	buffer.clear();
	m_mustRender = false;
}

void SDLPopupMenu::show(int x, int y) {
	if(m_Surface != NULL) {
		m_coords.x = x;
		m_coords.y = y;
		m_coords.w = m_dst.w;
		m_coords.h = m_dst.h;
		if(x + m_coords.w > SCREEN_WIDTH) {
			x -= m_coords.w;
			m_coords.x = x;
		}
		if(y + m_coords.h > SCREEN_HEIGHT) {
			y -= m_coords.h;
			m_coords.y = y;
		}
		apply_surface(x, y, m_Surface, m_Parent);
		m_isVisible = true;
	}
}

void SDLPopupMenu::hide() {
	m_isVisible = false;
}

void SDLPopupMenu::addItem(std::string item, bool active) {
	m_List.push_back(make_pair(item, active));
	m_mustRender = true;
}

void SDLPopupMenu::subtractItem(int num) {
	if(m_List.size() < num && num >= 0) {
		std::vector<std::pair<std::string, bool> >::iterator iter;
		iter = m_List.begin();
		iter += num;
		m_List.erase(iter);
		m_mustRender = true;
	}
}

void SDLPopupMenu::inputHandler() {
	int x = 0, y = 0, w = 0, h = 0;
	if(m_Event->type == SDL_MOUSEMOTION) {
		x = m_Event->motion.x;
		y = m_Event->motion.y;
		if((x > m_coords.x) && (x < m_coords.x + m_coords.w) && (y > m_coords.y) && (y < m_coords.y + m_coords.h)) {
			if(m_List.size() > 0) {
				TTF_SizeText(m_Font, m_List[0].first.c_str(), &w, &h);
				for(int i = 0; i < m_List.size(); i++) {
					if((y > (m_coords.y + (h * i))) && (y < (m_coords.y + (h * (i + 1))))) {
						doHighlight(i);
					}
				}
			}
		}
	} else if(m_Event->type == SDL_MOUSEBUTTONDOWN) {
		x = m_Event->button.x;
		y = m_Event->button.y;
		if((x > m_coords.x) && (x < m_coords.x + m_coords.w) && (y > m_coords.y) && (y < m_coords.y + m_coords.h)) {
			if(m_Event->button.button == SDL_BUTTON_LEFT) {
				if(m_List.size() > 0) {
					TTF_SizeText(m_Font, m_List[0].first.c_str(), &w, &h);
					for(int i = 0; i < m_List.size(); i++) {
						if((y > (m_coords.y + (h * i))) && (y < (m_coords.y + (h * (i + 1))))) {
							if(m_List[i].second) {
								doAction(i);
								hide();
							}
						} 
					}
				}
			}
		} else hide();
	}
}

void SDLPopupMenu::doHighlight(int num) {
	m_curr = num;
	int h = 0, w = 0;
	SDL_Rect dst;
	TTF_SizeText(m_Font, m_List[num].first.c_str(), &w, &h);
	SDL_Surface *highlightSurface = SDL_CreateRGBSurface(SDL_SWSURFACE | SDL_SRCALPHA, w, h, 32, 0, 0, 0, 0);
	SDL_SetAlpha(highlightSurface, SDL_SRCALPHA, 128);
	dst.x = 0;
	dst.y = 0;
	dst.w = w;
	dst.h = h;
	SDL_FillRect(highlightSurface, &dst, 0x0000ff);
	apply_surface(m_coords.x, m_coords.y + (num * h), highlightSurface, m_Parent);
}

void SDLPopupMenu::doAction(int num) {
	m_pParent->popupMenuAction(num);
}

void SDLPopupMenu::setParent(SDL_Surface *pParent) {
	m_Parent = pParent;
}

void SDLPopupMenu::setEvent(SDL_Event *event) {
	m_Event = event;
}

int SDLPopupMenu::getCurrentItem() {
	return m_curr;
}

void SDLPopupMenu::setActive(int num, bool state) {
	if(m_List.size() > num && num >= 0) {
		m_List[num].second = state;
		m_mustRender = true;
	}
}

bool SDLPopupMenu::isVisible() { return m_isVisible; }

bool SDLPopupMenu::mustRender() { return m_mustRender; }
	
